package com.market.web.controller;

import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import org.primefaces.event.TabChangeEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.market.domain.Location;
import com.market.domain.Order;
import com.market.domain.ProductPrice;
import com.market.domain.ProductTheme;
import com.market.domain.Promotion;
import com.market.domain.User;
import com.market.domain.Weekly;
import com.market.web.model.OrderModel;
import com.market.web.model.ShoppingCartModel;

@Controller("shoppingCartController")
@Scope("session")
public class ShoppingCartController {
	@Autowired
	private ShoppingCartModel shoppingCart;
	@Autowired
	private OrderController orderController;
	@Autowired
	private OrderModel orderModel;
	@Autowired
	private UserController userController;
	@Autowired
	private PromotionController promotionController;
	@Autowired
	private WeeklyController weeklyController;
	@Autowired
	private LocationController locationController;
	@Autowired
	private ProductThemeController productThemeController;

	private Boolean themesLoaded = Boolean.FALSE;

	public void init() {
		User customer = userController.getModel().getAuthenticatedUser();
		Location loc = locationController.fetchOne(customer
				.getDropOffLocation());
		List<Promotion> promotions = promotionController.fetchValidPromotion(
				shoppingCart.getOrderedDate(), loc.getId());
		List<Weekly> activeWeeklys = weeklyController.fetchActiveWeekly();
		shoppingCart.getActiveWeeklys().clear();
		for (Weekly weekly : activeWeeklys) {
			weekly = this.weeklyController.fetchOne(weekly);
			shoppingCart.getActiveWeeklys().add(weekly);
		}

		shoppingCart.setCustomer(customer);
		shoppingCart.setLocation(loc);
		shoppingCart.setPromotions(promotions);
		shoppingCart.setOrder(this.orderModel.getNewObject());

		if (shoppingCart.getNewRequiredDate() == null
				&& shoppingCart.getAvailablePickupDates() != null
				&& shoppingCart.getAvailablePickupDates().size() > 0) {
			shoppingCart.setNewRequiredDate(shoppingCart
					.getAvailablePickupDates().get(0));
		}
		this.shoppingCart.setIsInitialized(Boolean.TRUE);
	}

	/**
	 * Use admin control panel to initialize shopping cart.
	 */
	public void initByAdmin() {
		User customer = this.shoppingCart.getCustomer();
		Location loc = locationController.fetchOne(customer
				.getDropOffLocation());
		List<Promotion> promotions = promotionController.fetchValidPromotion(
				shoppingCart.getOrderedDate(), loc.getId());
		List<Weekly> activeWeeklys = weeklyController.fetchActiveWeekly();
		shoppingCart.getActiveWeeklys().clear();
		for (Weekly weekly : activeWeeklys) {
			weekly = this.weeklyController.fetchOne(weekly);
			shoppingCart.getActiveWeeklys().add(weekly);
		}

		shoppingCart.setCustomer(customer);
		shoppingCart.setLocation(loc);
		shoppingCart.setPromotions(promotions);
		shoppingCart.setOrder(this.orderModel.getNewObject());

		if (shoppingCart.getNewRequiredDate() == null
				&& shoppingCart.getAvailablePickupDatesForAdmin() != null
				&& shoppingCart.getAvailablePickupDatesForAdmin().size() > 0) {
			shoppingCart.setNewRequiredDate(shoppingCart
					.getAvailablePickupDatesForAdmin().get(0));
		}
		this.shoppingCart.setIsInitialized(Boolean.TRUE);
	}

	public String goShopping() {
		if (this.shoppingCart.getRequiredDate() != null
				&& !(this.shoppingCart.getRequiredDate()
						.equals(this.shoppingCart.getNewRequiredDate()))) {
			this.shoppingCart.emptyBasket(); // Choose a different date, empty
												// basket.
		}
		this.shoppingCart.setRequiredDate(this.shoppingCart
				.getNewRequiredDate());
		return "GO SHOPPING";
	}

	/**
	 * When shopping, if user switch between type and theme this method will be
	 * invoked.
	 * 
	 * @param event
	 */

	public void onTabChange(TabChangeEvent event) {
		List<ProductPrice> requiredWeekProductPrice = this.shoppingCart
				.getRequiredWeek().getProductPrices();
		if (event.getTab().getId().equalsIgnoreCase("theme")
				&& this.themesLoaded == Boolean.FALSE) {
			productThemeController.loadActiveProductThemes();
			List<ProductTheme> activeThemes = productThemeController.getModel()
					.getActiveProductThemes();
			for (int i = 0; i < activeThemes.size(); i++) {
				ProductTheme currentTheme = activeThemes.get(i);
				currentTheme = productThemeController.manager
						.fetchOne(currentTheme);
				currentTheme.importProductPrices(requiredWeekProductPrice);
				activeThemes.set(i, currentTheme);

			}

			ProductTheme onSaleTheme = new ProductTheme(); // Create "onSale"
															// theme
			onSaleTheme.importOnSaleProductPrices(requiredWeekProductPrice); // Add
																				// all
																				// on
																				// sale
																				// product
																				// from
																				// requiredWeek's
																				// product
																				// price
																				// list.
			if (onSaleTheme.getProductPrices().size() > 0) {
				activeThemes.add(onSaleTheme);// Add "onSale" theme to theme
												// list.
			}

			ProductTheme fromOurFarmTheme = new ProductTheme(); // Create
																// "fromOurFarmTheme"
																// theme
			fromOurFarmTheme
					.importFromOurFarmProductPrices(requiredWeekProductPrice);
			if (fromOurFarmTheme.getProductPrices().size() > 0) {
				activeThemes.add(fromOurFarmTheme);
			}

			ProductTheme farmDirectTheme = new ProductTheme();
			farmDirectTheme.importFarmDirectProductPrices(requiredWeekProductPrice);
			if(farmDirectTheme.getProductPrices().size()>0){
				activeThemes.add(farmDirectTheme);
			}
			
			productThemeController.getModel().setActiveProductThemes(
					activeThemes);
			this.themesLoaded = Boolean.TRUE; // Use this parameter to control
												// all themes can only be loaded
												// once.
		}
	}

	/**
	 * When switch between themes, this event will be invoked
	 * @param event
	 */
	public void onThemeTabChange(TabChangeEvent event) {
		String id = event.getTab().getId();
		ProductTheme currentTheme = productThemeController.manager
				.fetchOne(Long.parseLong(id));
		currentTheme.importProductPrices(this.shoppingCart.getRequiredWeek()
				.getProductPrices());
		List<ProductTheme> activeThemes = productThemeController.getModel()
				.getActiveProductThemes();
		for (int i = 0; i < activeThemes.size(); i++) {
			if (currentTheme.equalsId(activeThemes.get(i))) {
				activeThemes.set(i, currentTheme);
				break;
			}
		}
		this.productThemeController.getModel().setActiveProductThemes(
				activeThemes);
	}

	public String submitOrder() {

		if (this.shoppingCart.getOrder().getIsNew()) {
			Order order = orderModel.getNewObject();
			order.setCustomer(shoppingCart.getCustomer());
			order.setOrderedDate(Calendar.getInstance(new Locale("CA"))
					.getTime());
			order.setRequiredDate(shoppingCart.getRequiredDate().getDate());
			if (!this.shoppingCart.getIsFreeDelivery()) {
				order.setDeliveryFee(this.shoppingCart.getRequiredWeek()
						.getDeliveryFee());
			}
			order.setPickupTimeRangeLabel(shoppingCart.getRequiredDate()
					.getTimeRangeLabel());
			order.setOrderDetails(shoppingCart.getBasket());
			order.getPromotions().addAll(shoppingCart.getValidPromotions());
			if (shoppingCart.getIsCanConfirm()) {
				order.orderedToConfirmed(); // Copy ordered quantity and price
											// to
											// delivered, because this order
											// will be
											// confirmed;
				order = orderController.userConfirm(order);
			} else {
				order = orderController.userSave(order);
			}
			Double newBalance = this.shoppingCart.getCustomer().getBalance()
					- order.getPaidByCreditAmount(); // If customer have use
														// credit
														// to paid,update their
														// balance.
			this.shoppingCart.getCustomer().setBalance(newBalance);
			userController.getModel().getAuthenticatedUser().getOrders()
					.add(order);
		} else {
			orderController.save(this.shoppingCart.getOrder());
		}
		shoppingCart.emptyBasket();
		return "Order submit succeed";
	}

}
